package com.softserveinc.dao.impl;

import com.softserveinc.dao.IAuthoritiesDAO;
import com.softserveinc.dao.IUserDao;
import com.softserveinc.dao.mapper.RoleRowMapper;
import com.softserveinc.model.Role;
import com.softserveinc.model.User;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Repository;

import javax.sql.DataSource;
import java.util.List;

/**
 * dao for Authorities model
 */
@Repository
public class AuthoritiesDAO implements IAuthoritiesDAO {
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private IUserDao userDao;

    //get log4j handler
    private static final Logger logger = Logger.getLogger(AuthoritiesDAO.class);

    @Autowired
    public void setDataSource(@Qualifier("dataSource") DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }

    /**
     * Generates list of user authorities from database
     *
     * @param userDetails - user to get his authorities
     * @return - list of user authorities
     */
    @Override
    public List<GrantedAuthority> getUserAuthorities(User userDetails) {
        try {
            int id = userDetails.getId();
            return jdbcTemplate.query("SELECT * from role" +
                    " inner join user_role on user_role.role_id = role.role_id WHERE user_role.user_id=?",
                    new Object[]{id}, new RoleRowMapper());
        } catch (DataAccessException e) {
            logger.debug(e.getStackTrace());
            return null;
        }
    }

    /**
     * Removes authority from user
     *
     * @param authority   - authority to remove
     * @param userDetails - user for authority removing
     */
    @Override
    public void revokeAuthority(GrantedAuthority authority, User userDetails) {
        try {
            int id = userDetails.getId();
            jdbcTemplate.update("DELETE FROM  user_role where user_id=? and role_id=?",
                    id, authority.getAuthority());
        } catch (DataAccessException e) {
            logger.debug( e.getStackTrace());
        }
    }

    /**
     * Grants authority for user
     *
     * @param authority   - authority for user
     * @param userDetails - user for granting
     */
    @Override
    public void grantAuthority(GrantedAuthority authority, User userDetails) {
        try {

            Role role = (Role) authority;
            int authId = role.getId();
            User user = userDao.selectUser(userDetails.getLogin());
            int userId = user.getId();
            List<GrantedAuthority> roles;
            int roleId;
            roles = jdbcTemplate.query("SELECT * FROM role WHERE role_id = ?", new Object[]{authId}, new RoleRowMapper());
            Role userRole = (Role) roles.get(0);
            roleId = userRole.getId();
            jdbcTemplate.update("insert into user_role(USER_ID, ROLE_ID) values (?,?)", userId, roleId);
        } catch (DataAccessException e) {
            logger.debug( e.getStackTrace());
        }
    }
}
